#ifndef ANT_HPP
#define ANT_HPP

#include "palette.hpp"
#include "graph.hpp"
#include "trace.hpp"
#include <vector>
#include <list>

typedef std::vector < long > ant_route_v;

class ant_c
{
        typedef enum
        {
                ANT_STATE_INVALID,
                ANT_STATE_IDLE,
                ANT_STATE_IN_TOUR,
                ANT_STATE_COMPLETED,
        } ant_state_e;

        typedef std::list < long >                      colour_class_l;
        typedef std::vector < colour_class_l * >        colour_classes_v;

        long                            colour_bound;
        const graph_c *                 graph;
        palette_c *                     palette;
        long                            current_colour;
        palette_c::pheromone_t *        current_path;
        long                            current_stage_time;
        long                            max_colour;
        ant_route_v *                   route;
        bool                            route_is_legal;
        long                            tour_time;
        long                            stage_id;
        ant_state_e                     state;
        colour_classes_v *              colour_classes;
        

        void    find_next_colour           ( void );
        void    measure_stage_time         ( void );
        void    create_pheromone_path      ( void );
        void    after_stage_state_update   ( void );

public:
        ~ant_c  ( void );
        ant_c   ( void );
        ant_c   ( const ant_c & right );
        ant_c   ( graph_c * graph, palette_c *  palette, long colour_bound );

        void                    restart_tour            ( void );
        void                    run_next_stage          ( void );
        long                    get_tour_time           ( void ) const;
        bool                    tour_completed          ( void ) const;
        const ant_route_v *     get_route               ( void ) const;
        long                    get_colours_count       ( void ) const;
        bool                    colouring_is_valid      ( void ) const;
        void                    trace                   ( trace_level_e trace_level = TRACE_LEVEL_LOW ) const;

        ant_c &         operator= ( const ant_c & right );  
};

#endif

